#include"server.h"

#define DEV_UART 	"/dev/ttyUSB0"

pthread_cond_t js,dq;
int semsid;             //与输出进程的同步信号灯集
int shmid;                    //共享内存id
int msgid;				//互斥锁id
struct shm_addr *p;			//更新内存地址
struct storage_info myinfo;  //仓库信息
struct sendEnv mydata;	     //接收到的信息
int k = 0;             //是否接受到新信息的标志位
pthread_mutex_t lock; //端口读取端与向共享内存写入段使用的互斥锁
linklist_t *head,*lost;
int dev_uart_fd;     //m0端口
int gd_fd;
int devid;

void serial_init(int fd)
{
    struct termios options;
    tcgetattr(fd, &options);
    options.c_cflag |= ( CLOCAL | CREAD );
    options.c_cflag &= ~CSIZE;
    options.c_cflag &= ~CRTSCTS;
    options.c_cflag |= CS8;
    options.c_cflag &= ~CSTOPB;
    options.c_iflag |= IGNPAR;
    options.c_iflag &= ~(ICRNL | IXON);
    options.c_oflag = 0;
    options.c_lflag = 0;

    cfsetispeed(&options, B115200);
    cfsetospeed(&options, B115200);
    tcsetattr(fd,TCSANOW,&options);
}

void init()
{
	int ret = 0;
	key_t key;
	key = ftok("/app", 'i');

	pthread_mutex_init(&lock,NULL);
	pthread_cond_init(&js,NULL);
	pthread_cond_init(&dq,NULL);

	shmid = shmget(key,sizeof(struct shm_addr),IPC_CREAT|IPC_EXCL|0777);
	if(shmid < 0)
	{
		if(errno == EEXIST)
		{
			shmid = shmget(key,0,0777);
		}else
		{
			perror("fail to shmget");
			exit(1);
		}
	}
	if((p =(struct shm_addr *)shmat(shmid,NULL,0)) == (struct shm_addr *)-1)
	{
		perror("fail to shmat");
		exit(1);
	}
	
	//建立信号灯集
	semsid = semget(key,1,IPC_CREAT|IPC_EXCL|0777);
	if(semsid < 0)
	{
		if(errno == EEXIST)
		{
			semsid = semget(key,1,0777);
		}else
		{
			perror("fail to semget");
			exit(1);
		}
	}
	//信号灯集初始化
	semctl(semsid,0,SETVAL,1);


	//
	key = ftok("/app", 'g');
	msgid = msgget(key,IPC_CREAT|0777);
	
	ret = mkfifo("/tmp/webcam",O_CREAT|0777);
	if(ret < 0)
	{
		perror("mkfifo failed:");
		return ;
	}
	printf("init ok.\n");
	
}

void set_m0(char text)
{
	printf("%s get 0x%x\n",__FUNCTION__,text);
	
	int type = text/16;
	int set = text%16;
	char cmd = 0;
	switch(type)
	{
		case 8:
			cmd = 0x80 + set;
			break;
		case 9:
			cmd = 0x90 + set;
			break;
		case 10:
			cmd = 0xa0 + set;
			break;
		case 11:
			cmd = 0xb0 + set;
			break;
	}
	write(dev_uart_fd,&cmd,sizeof(cmd));
}

void * todriver(void *argv)
{
	struct msg mymsg;
	int cmd;
	int ret = 0;
	char buf_cmd[10];

	printf("this is todriver\n");

	devid = open("/dev/led2",O_RDWR);
	if(devid < 0)
	{
		printf("open dev failed.\n");
		return ;
	}
	else
		printf("open led2 ok.\n");



	gd_fd = open("/tmp/webcam",O_WRONLY,0666);
	while(1)
	{
		printf("began wait info.\n");
		msgrcv(msgid,(void *)&mymsg,sizeof(struct msg)-sizeof(long),0,0);

		if(mymsg.type == 1L )
		{
			printf("%s get %d:0x%x\n",__FUNCTION__,mymsg.msgtype,mymsg.text[0]);
			switch(mymsg.msgtype)
			{
			case 1L:    //a8 led
				switch(mymsg.text[0])
				{
					case 0x10:
						ioctl(devid,LED2_OFF);
						break;
					case 0x11:
						ioctl(devid,LED2_ON);
						break;
					case 0x20:
						ioctl(devid,LED3_OFF);
						break;
					case 0x22:
						ioctl(devid,LED3_ON);
						break;
				};
				break;
			case 2L:	//a8 pwm
				if(mymsg.text[0] == 0)
					ioctl(devid,BUZZER_OFF);
				else
					ioctl(devid,BUZZER_ON);
				break;
			case 3L:
				
				printf("goto 3L:\n");
				switch(mymsg.text[0])
				{
					case 1:
						strcpy(buf_cmd,"one");
						break;
					case 3:
						strcpy(buf_cmd,"three");
						break;
					case 5:
						strcpy(buf_cmd,"five");
						break;
					case 7:
						strcpy(buf_cmd,"seven");
						break;
					case 9:
						strcpy(buf_cmd,"nine");
						break;
					default:
						break;
				}
				printf("buf_cmd is %s\n",buf_cmd);
				ret = write(gd_fd,buf_cmd,sizeof(buf_cmd));
				printf("write %d:%s\n",ret,buf_cmd);
				break;
			case 4L:	//m0
				set_m0(mymsg.text[0]);
				break;
			}//switch end
		}//if(msg.type == 1l) end	
	}//while(1) end
	close(gd_fd);
	close(devid);
}//void * todriver(void * argv) end

void * saveInfo(void *argv)
{
	printf("this is saveinfo start\n");
	
	int flag = 1;
	
	while(1)
	{	
		pthread_mutex_lock(&lock);
		sem_p(semsid,0); //输出进程是否占用共享内存
		myinfo.storage_status = 1;
		myinfo.led_status = 1;
		myinfo.buzzer_status = 1;
		myinfo.fan_status = 1;
		myinfo.seg_status = 1;
		myinfo.x = mydata.x;
		myinfo.y = mydata.y;
		myinfo.z = mydata.z;
		if(mydata.temp[0] > myinfo.temperatureMAX)
			myinfo.temperatureMAX = mydata.temp[0];
		if(mydata.temp[0] < myinfo.temperatureMIN)
			myinfo.temperatureMIN = mydata.temp[0];
		myinfo.temperature = mydata.temp[0]; 
		
		if(mydata.hum[0] > myinfo.humidityMAX)
			myinfo.humidityMAX = mydata.hum[0];
		if(mydata.hum[0] < myinfo.humidityMIN)
			myinfo.humidityMIN = mydata.hum[0];
		myinfo.humidity = mydata.hum[0]; 
		
		if(mydata.ill > myinfo.illuminationMAX)
			myinfo.illuminationMAX = mydata.ill;
		if(mydata.ill < myinfo.illuminationMIN)
			myinfo.illuminationMIN = mydata.ill;
		myinfo.illumination = mydata.ill; 
		
		myinfo.battery = mydata.bet;
		myinfo.adc = mydata.adc;
		if(mydata.adc > myinfo.adcMIN)
			myinfo.adcMIN = mydata.adc;
		
		p->rt_status.storage_no[mydata.snum] = myinfo;
		printf("save:%d,%d,%d\n",myinfo.x,myinfo.y,myinfo.z);
		pthread_mutex_unlock(&lock);
		sem_v(semsid,0); 
		
		if(mydata.z > 225 || mydata.z < 30 )
		{
			if(flag == 0)
			{
				
				ioctl(devid,BUZZER_ON);
				flag = 1;
			}
		}
		else
		{
			if(flag == 1)
			{
				ioctl(devid,BUZZER_OFF);
				flag = 0;
			}
		}
		
		sleep(1);
	}
}

int main(int argc,char *argv[])
{
	pthread_t pthread;
	pthread_t pth_tod;
	
	
    if((dev_uart_fd = open(DEV_UART,O_RDWR)) < 0)
    {
        perror ("open uart err");
        return -1;
    }
	
	serial_init (dev_uart_fd);

	init();

	int ret;
	pthread_create(&pthread,NULL,&saveInfo,NULL);
	pthread_create(&pth_tod,NULL,&todriver,NULL);

	while(1)
	{
		printf("above on the mutex!\n");
		pthread_mutex_lock(&lock);
		ret = read(dev_uart_fd,&mydata,sizeof(struct sendEnv));
		
		printf("read %d, %d:%d,%d,%d\n",ret,mydata.snum,mydata.x,mydata.y,mydata.z);
		pthread_mutex_unlock(&lock);
		sleep(1);
		
	}
		
	close(dev_uart_fd);
	return 0;
}
